package apii.servlet.stud;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import apii.server.ServerThings;
import apii.servlet.ServletUtils;
import apii.servlet.UserRequesterData;
import apii.utils.DoubleString;

/**
 * 
 * @author evgeniy
 * 
 */
public class ViewLabServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public static final String UPLOAD = "upload";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ViewLabServlet() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			UserRequesterData urd = ServletUtils.extractRequesterData(request
					.getSession());
			if ((urd.sessionId == null) || !urd.logged
					|| (urd.role != UserRequesterData.ROLE_STUD)) {
				ServletUtils.redirectToUrl(response, "/login");
			} else if (urd.userId == UserRequesterData.UNKNOWN_ID) {
				throw new Error();
			} else {
				int labId = (Integer) request
						.getAttribute(StudRootServlet.LAB_ID);
				int discId = (Integer) request
						.getAttribute(StudRootServlet.DISCIPLINE_ID);
				LabInfoPack infoPack = getLabInfo(labId, urd.userId);
				String zipUploadHandlerName = ServletUtils.PREFIX + "/stud/"
						+ StudRootServlet.ALL_DISCIPLINES + "/"
						+ ServletUtils.getDisciplineURLElement(discId) + "/"
						+ ServletUtils.getLabURLElement(labId) + "/"
						+ StudRootServlet.UPLOAD_ZIP;

				//
				PrintWriter pw = response.getWriter();
				// TODO
				ServletUtils.startCommonStudDoc(pw, urd, "Просмотр лабы");
				pw.println("<center>" + infoPack.name + "</center>");
				pw.println("<form action=\"" + zipUploadHandlerName
						+ "\" method=\"post\" "
						+ "enctype=\"multipart/form-data\">");
				pw.println("<input type=\"file\" name=\""
						+ ServletUtils.ZIP_ARCHIVE + "\"><br>");
				pw.println("<input type=\"submit\" value=\"Загрузить\"><br>");
				pw.println("</form>");
				pw.println("<table>");
				pw.println("<tr>");
				pw.println("<td>Revision</td>");
				pw.println("<td>Name(path)</td>");
				for (CodeInfo ci : infoPack.files) {
					String referenceString = "<a href =\""
							+ ServletUtils.PREFIX + "/stud/all_disciplines/"
							+ ServletUtils.getDisciplineURLElement(discId)
							+ "/" + ServletUtils.getLabURLElement(labId) + "/"
							+ ServletUtils.getCodeURLElement(ci.id) + "\">"
							+ ci.name + "</a>";
					pw.println("<tr>");
					pw.println("<td>" + ci.revision + "</td>");
					pw.println("<td>" + referenceString + "</td>");
					pw.println("</tr>");
				}
				pw.println("</table>");
				ServletUtils.closeCommonStudDoc(pw, urd);
			}
		} catch (SQLException ex) {
			ex.printStackTrace();
			ServletUtils.redirectToErrorPage(response, ex.getMessage());
		}
	}

	private LabInfoPack getLabInfo(int labId, int userId) throws SQLException {
		List<CodeInfo> codeInfos = new ArrayList<CodeInfo>();
		String name = null;
		Connection c = ServerThings.getThings().getConnection();
		Statement s = c.createStatement();
		ResultSet labInfoRS = s
				.executeQuery("SELECT apii.labs.name FROM apii.labs "
						+ "WHERE apii.labs.lab_id = '" + labId + "'");
		if (!labInfoRS.next()) {
			throw new Error();
		}
		name = labInfoRS.getString(1);
		codeInfos = CodeInfo.extractCodeInfos(c, userId, labId);

		c.close();
		return new LabInfoPack(codeInfos, name);
	}

	private class LabInfoPack {
		public final List<CodeInfo> files;
		public final String name;

		public LabInfoPack(List<CodeInfo> files, String name) {
			this.files = files;
			this.name = name;
		}
	}

	private static class CodeInfo {

		public static final int UNCHECKED_STATE = 1;
		public static final int CHECKED_STATE = 2;
		public static final int ALERTED_STATE = 3;

		public final int id;
		public final int revision;
		public final String name;
		public final int checkedState;

		public CodeInfo(int id, int revision, String name, int checkedState) {
			this.id = id;
			this.revision = revision;
			this.name = name;
			this.checkedState = checkedState;
		}

		public static final List<CodeInfo> extractCodeInfos(Connection c,
				int userId, int labId) throws SQLException {
			List<CodeInfo> result = new ArrayList<CodeInfo>();
			Statement s = c.createStatement();
			// TODO: implement plagiarism extraction
			// TODO: make prepared statement
			ResultSet codesRS = s
					.executeQuery("SELECT apii.codes.code_id, apii.codes.revision, "
							+ "apii.codes.name, apii.codes.checked "
							+ "FROM apii.codes "
							+ "WHERE apii.codes.user_id = '"
							+ userId
							+ "' "
							+ "AND apii.codes.lab_id = '" + labId + "'");

			while (codesRS.next()) {
				CodeInfo ci = new CodeInfo(codesRS.getInt(1),
						codesRS.getInt(2), codesRS.getString(3),
						codesRS.getBoolean(4) ? CodeInfo.CHECKED_STATE
								: CodeInfo.UNCHECKED_STATE);
				result.add(ci);
			}

			return result;
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ServletUtils.redirectToIllegalPage(response);
	}
}